package com.itheima.appserver.service;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.util.StrUtil;
import com.itheima.commons.model.domain.Admin;
import com.itheima.commons.model.domain.UserFreeze;
import com.itheima.commons.model.domain.UserLoginRecord;
import com.itheima.commons.model.mongo.Publish;
import com.itheima.commons.model.vo.LogDetailsVo;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.itheima.commons.model.domain.UserInfo;
import com.itheima.commons.model.vo.OperationLogVo;
import com.itheima.commons.model.vo.RegistrationStayVo;
import com.itheima.commons.utils.MakePercentage;
import com.itheima.dubbo.interfaces.*;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * 额外两个接口
 */
@Service
public class AdditionalService {

    @Reference
    private UserInfoApi userInfoApi;

    @Reference
    private AdminApi adminApi;

    @Reference
    private UserLoginRecordApi userLoginRecordApi;

    @Reference
    private UserFreezeApi userFreezeApi;

    @Reference
    private PublishApi publishApi;


    public List<RegistrationStayVo> registrationStay(Map<String, String> params) {
        //前端传时间区间String startTime  String endTime,性别: String gender  man或woman

        String sex = params.get("gender");
        Date endTime = DateUtil.parse(params.get("endTime"), "yyyy-MM-dd");
        Date startTime = DateUtil.parse(params.get("startTime"), "yyyy-MM-dd");


        //获取时间区间内所以的时间
        long betweenDay = DateUtil.between(startTime, endTime, DateUnit.DAY);
        //区间内的时间集合
        List<RegistrationStayVo> registrationStayVos = new ArrayList<>();
        for (long i = 0; i <= betweenDay; i++) {

            RegistrationStayVo registrationStayVo = new RegistrationStayVo();
            //这一天的开始时间
            Date startOfDay = DateUtil.offsetDay(startTime, Convert.toInt(i));
            startOfDay = new Date(startOfDay.getTime());
            //这一天的结束时间
            Date endOfDay = DateUtil.endOfDay(startOfDay);
            endOfDay = new Date(endOfDay.getTime());
            //获取但天注册人的userinfo集合
            List<UserInfo> countByDate = userInfoApi.findCountByDateAndGender(startOfDay, endOfDay, sex);
            //获取用户id
            List<Long> userIds = CollUtil.getFieldValues(countByDate, "userId", Long.class);
            //根据时间查当天注册总数
            int peopleCounts = countByDate.size();

            //一天
            Integer count1 = userLoginRecordApi.queryCountByDateAndUserIds(userIds, startOfDay, 1);
            //两天
            Integer count2 = userLoginRecordApi.queryCountByDateAndUserIds(userIds, startOfDay, 2);
            //三天
            Integer count3 = userLoginRecordApi.queryCountByDateAndUserIds(userIds, startOfDay, 3);
            //四天
            Integer count4 = userLoginRecordApi.queryCountByDateAndUserIds(userIds, startOfDay, 4);
            //五天
            Integer count5 = userLoginRecordApi.queryCountByDateAndUserIds(userIds, startOfDay, 5);
            //六天
            Integer count6 = userLoginRecordApi.queryCountByDateAndUserIds(userIds, startOfDay, 6);
            //七天
            Integer count7 = userLoginRecordApi.queryCountByDateAndUserIds(userIds, startOfDay, 7);
            //一个月
            Integer count30 = userLoginRecordApi.queryCountByDateAndUserIds(userIds, startOfDay, 30);

            //set存留百分比
            registrationStayVo.setOneDayAfter(MakePercentage.makePercentage(count1, peopleCounts));
            registrationStayVo.setTwoDayAfter(MakePercentage.makePercentage(count2, peopleCounts));
            registrationStayVo.setThreeDayAfter(MakePercentage.makePercentage(count3, peopleCounts));
            registrationStayVo.setFourDayAfter(MakePercentage.makePercentage(count4, peopleCounts));
            registrationStayVo.setFiveDayAfter(MakePercentage.makePercentage(count5, peopleCounts));
            registrationStayVo.setSixDayAfter(MakePercentage.makePercentage(count6, peopleCounts));
            registrationStayVo.setSevenDayAfter(MakePercentage.makePercentage(count7, peopleCounts));
            registrationStayVo.setOneMonthAfter(MakePercentage.makePercentage(count30, peopleCounts));
            //set总数
            registrationStayVo.setRegisterCounts(Convert.toLong(peopleCounts));
            //set日期
            registrationStayVo.setRegisterTime(DateUtil.format(startOfDay, "yyyy/MM/dd"));

            registrationStayVos.add(registrationStayVo);
        }
        return registrationStayVos;
    }

    /**
     * 运营日志
     *
     * @param params
     * @return
     */
    public List<OperationLogVo> operationLog(Map<String, String> params) {
        //获得需要的数据
        List<OperationLogVo> operationLogVos = new ArrayList<>();
        //分页
        Integer page = 1;
        Integer pagesize = 10;
        if (StrUtil.isNotBlank(params.get("page"))) {
            page = Convert.toInt(params.get("page"));
        }
        if (StrUtil.isNotBlank(params.get("pagesize"))) {
            pagesize = Convert.toInt(params.get("pagesize"));
        }
        //前端传时间区间String startTime  String endTime,
        // 操作人姓名: String adminName 操作内容 ：String operationContent;
        String adminName = params.get("adminName");
        String operationContent = params.get("operationContent");
        Date endTime = DateUtil.parse(params.get("endTime"), "yyyy-MM-dd");
        Date startTime = DateUtil.parse(params.get("startTime"), "yyyy-MM-dd");

        long endTimeTime = endTime.getTime();
        Date endDate = new Date(endTimeTime);
        long startTimeTime = startTime.getTime();
        Date startDate = new Date(startTimeTime);
        //根据管理员的姓名，模糊查询到管理员的id集合
        List<Admin> admin = adminApi.queryByName(adminName);
        List<Long> adminIds = CollUtil.getFieldValues(admin, "adminId", Long.class);
        //然后根据id，和时间还有操作内容（模糊查询,如果没有传值，则全部查询）
        //用adminIds查冻结表获取数据(集合)
        List<UserFreeze> userFreezes = userFreezeApi.queryByAdminIdsAndTimeAndFreezeRemarks(adminIds, endDate, startDate, operationContent);
        for (UserFreeze userFreeze : userFreezes) {
            Long adminId = userFreeze.getAdminId();
            Admin admins = adminApi.queryWithId(adminId);
            operationLogVos.add(new OperationLogVo(userFreeze,admins.getUsername()));
        }

        //用adminIds查审核表(public)获取数据(集合)
        List<Publish> publishes = publishApi.queryByAdminIdsAndTimeAndFreezeRemarks(adminIds, endDate, startDate,operationContent);
        for (Publish publish : publishes) {
            Long opsUserId = publish.getOpsUserId();
            Admin admins = adminApi.queryWithId(opsUserId);
            operationLogVos.add(new OperationLogVo(publish,admins.getUsername()));
        }



        //按时间降序
        operationLogVos = CollUtil.sort(operationLogVos, new Comparator<OperationLogVo>() {
            @Override
            public int compare(OperationLogVo o1, OperationLogVo o2) {
                // 按照操作时间降序(时间戳最大在上)
                Date parse1 = DateUtil.parse(o1.getOperationTime());
                Date parse2 = DateUtil.parse(o2.getOperationTime());

                if (parse1.getTime()>parse2.getTime()) {
                    return 1;
                }
                if (parse1.getTime()==parse2.getTime()) {
                    return 0;
                }
                return -1;
            }
        });

        //遍历加序号
        for (int i = 0; i < operationLogVos.size(); i++) {
            OperationLogVo operationLogVo = operationLogVos.get(i);
            operationLogVo.setId(Convert.toLong(i+1));
        }

        //分页后的集合对象
        List<OperationLogVo> operationLogVoss = new ArrayList<>();

        //手动分页集合  集合为示例  记得改
        for (int i = (page-1)*pagesize; i < ((page*pagesize)<operationLogVos.size()?(page*pagesize):operationLogVos.size()); i++) {
                operationLogVoss.add(operationLogVos.get(i));
        }

        return operationLogVoss;
    }
}
